home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz Kr0nlcKLeZ 1 / HaCKeRz Kr0nlcKLeZ.iso / chibacity / gbbdisk.arj / ANTIVIR / GBINTEG.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-06-15  |  11.8 KB  |  377 lines

  1. program giant_black_book_integ_checker;
  2.  
  3. uses dos,crt;
  4.  
  5. const
  6.   MAX_ENTRIES      =2000;               {Max number of files this can handle}
  7. type
  8.   LogRec_Type      =record
  9.     Name           :string[80];
  10.     Time           :longint;
  11.     Size           :longint;
  12.     Checksum       :longint;
  13.     Found          :boolean;
  14.     end;
  15. var
  16.   LstFile          :text;                                      {listing file}
  17.   LogFile          :file of LogRec_Type;                           {log file}
  18.   LogEntries       :longint;                          {# entries in log file}
  19.   Log              :array[1..MAX_ENTRIES] of ^LogRec_Type;      {log entries}
  20.   j                :word;
  21.   SearchDir        :string;                              {directory to check}
  22.   CurrDir          :string;                   {directory program called from}
  23.  
  24. {This routine just makes a string upper case}
  25. function UpString(s:string):string;
  26. var
  27.   i                :word;
  28. begin
  29.   for i:=1 to length(s) do s[j]:=UpCase(s[j]);
  30.   UpString:=s;
  31. end;
  32.  
  33. {This function searches the log in memory for a match on the file name.
  34.  To use it, pass the name of the file in fname. If a match is found, the
  35.  function returns true, and FN is set to the index in Log[] which is the
  36.  proper record. If no match is found, the function returns false.}
  37. function SearchLog(fname:string;var FN:word):boolean;
  38. var
  39.   j                :word;
  40. begin
  41.   fname:=UpString(fname);
  42.   if LogEntries>0 then for j:=1 to LogEntries do
  43.     begin
  44.       if fname=Log[j]^.Name then
  45.         begin
  46.           SearchLog:=true;
  47.           FN:=j;
  48.           exit;
  49.         end;
  50.     end;
  51.   SearchLog:=false;
  52. end;
  53.  
  54. {This function calcuates the checksum of the file whose name is passed to
  55.  it. The return value is the checksum.}
  56. function Get_Checksum(FName:string):longint;
  57. var
  58.   F                :file;
  59.   cs               :longint;
  60.   j,x              :integer;
  61.   buf              :array[0..511] of byte;
  62. begin
  63.   cs:=0;
  64.   assign(F,FName);
  65.   reset(F,1);
  66.   repeat
  67.     blockread(F,buf,512,x);
  68.     if x>0 then for j:=0 to x-1 do cs:=cs+buf[j];
  69.   until eof(F);
  70.   close(F);
  71.   Get_Checksum:=cs;
  72. end;
  73.  
  74. {This routine checks the integrity of one complete subdirectory and all its
  75.  subdirectories. The directory name (with a final \) is passed to it. It is
  76.  called recursively. This checks all COM and EXE files.}
  77. procedure check_dir(dir:string);
  78. var
  79.   SR               :SearchRec;                  {Record used by FindFirst}
  80.   Checksum         :Longint;                    {temporary variables}
  81.   FN               :word;
  82.   cmd              :char;
  83. begin
  84.   dir:=UpString(dir);
  85.   FindFirst(dir+'*.com',AnyFile,SR);            {first check COM files}
  86.   while DosError=0 do
  87.     begin
  88.       if SearchLog(dir+SR.Name,FN) then
  89.         begin
  90.           Checksum:=Get_Checksum(dir+SR.Name);
  91.           if (Log[FN]^.Time<>SR.Time) or (Log[FN]^.Size<>SR.Size)
  92.            or (Log[FN]^.Checksum<>Checksum) then
  93.             begin
  94.               write(dir+SR.Name,' has changed!',#7,#7,#7,' Do you want to update its record? ');
  95.               write(LstFile,dir+SR.Name,' has changed! Do you want to update its record? ');
  96.               repeat cmd:=UpCase(ReadKey) until cmd in ['Y','N'];
  97.               if cmd='Y' then
  98.                 begin
  99.                   Log[FN]^.Time:=SR.Time;
  100.                   Log[FN]^.Size:=SR.Size;
  101.                   Log[FN]^.Checksum:=Checksum;
  102.                   Log[FN]^.Found:=True;
  103.                 end;
  104.               writeln(cmd);
  105.               writeln(LstFile,cmd);
  106.             end
  107.           else
  108.             begin
  109.               writeln(dir+SR.Name,' validated.');
  110.               Log[FN]^.Found:=True;
  111.             end;
  112.         end
  113.       else
  114.         begin
  115.           if LogEntries<MAX_ENTRIES then
  116.             begin
  117.               writeln('New file: ',dir+SR.Name,'. ADDED to log.');
  118.               writeln(LstFile,'New file: ',dir+SR.Name,'. ADDED to log.');
  119.               LogEntries:=LogEntries+1;
  120.               new(Log[LogEntries]);
  121.               Log[LogEntries]^.Name:=dir+SR.Name;
  122.               Log[LogEntries]^.Time:=SR.Time;
  123.               Log[LogEntries]^.Size:=SR.Size;
  124.               Log[LogEntries]^.Checksum:=Get_Checksum(dir+SR.Name);
  125.               Log[LogEntries]^.Found:=True;
  126.             end
  127.           else
  128.             begin
  129.               writeln('TOO MANY ENTRIES. COULD NOT ADD ',dir+SR.Name,'.');
  130.               writeln(LstFile,'TOO MANY ENTRIES. COULD NOT ADD ',dir+SR.Name,'.');
  131.             end;
  132.         end;
  133.       FindNext(SR);
  134.     end;
  135.  
  136.   FindFirst(dir+'*.exe',AnyFile,SR);            {now check EXE files}
  137.   while DosError=0 do
  138.     begin
  139.       if SearchLog(dir+SR.Name,FN) then
  140.         begin
  141.           Checksum:=Get_Checksum(dir+SR.Name);
  142.           if (Log[FN]^.Time<>SR.Time) or (Log[FN]^.Size<>SR.Size)
  143.            or (Log[FN]^.Checksum<>Checksum) then
  144.             begin
  145.               write(dir+SR.Name,' has changed!',#7,#7,#7,' Do you want to update its record? ');
  146.               write(LstFile,dir+SR.Name,' has changed! Do you want to update its record? ');
  147.               repeat cmd:=UpCase(ReadKey) until cmd in ['Y','N'];
  148.               if cmd='Y' then
  149.                 begin
  150.                   Log[FN]^.Time:=SR.Time;
  151.                   Log[FN]^.Size:=SR.Size;
  152.                   Log[FN]^.Checksum:=Checksum;
  153.                   Log[FN]^.Found:=True;
  154.                 end;
  155.               writeln(cmd);
  156.               writeln(LstFile,cmd);
  157.             end
  158.           else
  159.             begin
  160.               writeln(dir+SR.Name,' validated.');
  161.               Log[FN]^.Found:=true;
  162.             end;
  163.         end
  164.       else
  165.         begin
  166.           if LogEntries<MAX_ENTRIES then
  167.             begin
  168.               writeln('New file: ',dir+SR.Name,'. ADDED to log.');
  169.               writeln(LstFile,'New file: ',dir+SR.Name,'. ADDED to log.');
  170.               LogEntries:=LogEntries+1;
  171.               new(Log[LogEntries]);
  172.               Log[LogEntries]^.Name:=dir+SR.Name;
  173.               Log[LogEntries]^.Time:=SR.Time;
  174.               Log[LogEntries]^.Size:=SR.Size;
  175.               Log[LogEntries]^.Checksum:=Get_Checksum(dir+SR.Name);
  176.               Log[LogEntries]^.Found:=True;
  177.             end
  178.           else
  179.             begin
  180.               writeln('TOO MANY ENTRIES. COULD NOT ADD ',dir+SR.Name,'.');
  181.               writeln(LstFile,'TOO MANY ENTRIES. COULD NOT ADD ',dir+SR.Name,'.');
  182.             end;
  183.         end;
  184.       FindNext(SR);
  185.     end;
  186.  
  187.   FindFirst('*.*',Directory,SR);            {finally, check subdirectories}
  188.   while DosError=0 do
  189.     begin
  190.       if (SR.Attr and Directory <> 0) and (SR.Name[1]<>'.') then
  191.         begin
  192.           ChDir(SR.Name);
  193.           check_dir(dir+SR.Name+'\');
  194.           ChDir('..');
  195.         end;
  196.       FindNext(SR);
  197.     end;
  198. end;
  199.  
  200. {This procedure checks the master boot sector and the boot sector's integrity}
  201. procedure check_boot;
  202. var
  203.   FN,j             :word;
  204.   cs               :longint;
  205.   buf              :array[0..511] of byte;
  206.   r                :registers;
  207.   cmd              :char;
  208.   currdrv          :byte;
  209. begin
  210.   r.ah:=$19;
  211.   intr($21,r);
  212.   currdrv:=r.al;
  213.   if currdrv>=2 then currdrv:=currdrv+$80-2;
  214.  
  215.   if currdrv=$80 then
  216.     begin
  217.       r.ax:=$201;                   {read boot sector/master boot sector}
  218.       r.bx:=ofs(buf);
  219.       r.es:=sseg;
  220.       r.cx:=1;
  221.       r.dx:=$80;
  222.       intr($13,r);
  223.       r.ax:=$201;
  224.       intr($13,r);
  225.       cs:=0;
  226.       for j:=0 to 511 do cs:=cs+buf[j];
  227.  
  228.       if SearchLog('**MBS',FN) then
  229.         begin
  230.           Log[FN]^.Found:=True;
  231.           if Log[FN]^.Checksum=cs then writeln('Master Boot Sector verified.')
  232.           else
  233.             begin
  234.               write('Master Boot Sector has changed! Update log file? ');
  235.               write(LstFile,'Master Boot Sector has changed! Update log file? ');
  236.               repeat cmd:=UpCase(ReadKey) until cmd in ['Y','N'];
  237.               if cmd='Y' then Log[FN]^.Checksum:=cs;
  238.               writeln(cmd);
  239.               writeln(LstFile,cmd);
  240.             end;
  241.         end
  242.       else
  243.         begin
  244.           writeln('Master Boot Sector data ADDED to log.');
  245.           writeln(LstFile,'Master Boot Sector data ADDED to log.');
  246.           LogEntries:=LogEntries+1;
  247.           new(Log[LogEntries]);
  248.           Log[LogEntries]^.Name:='**MBS';
  249.           Log[LogEntries]^.Checksum:=cs;
  250.           Log[LogEntries]^.Found:=True;
  251.         end;
  252.       j:=$1BE;
  253.       while (j<$1FE) and (buf[j]<>$80) do j:=j+$10;
  254.       if buf[j]=$80 then
  255.         begin
  256.           r.dx:=buf[j]+256*buf[j+1];
  257.           r.cx:=buf[j+2]+256*buf[j+3];
  258.         end
  259.       else exit;
  260.     end
  261.   else
  262.     begin
  263.       r.cx:=1;
  264.       r.dx:=currdrv;
  265.     end;
  266.   if CurrDrv<$81 then
  267.     begin
  268.       r.ax:=$201;
  269.       r.bx:=ofs(buf);
  270.       r.es:=sseg;
  271.       intr($13,r);
  272.       r.ax:=$201;
  273.       intr($13,r);
  274.       cs:=0;
  275.       for j:=0 to 511 do cs:=cs+buf[j];
  276.  
  277.       if SearchLog('**BOOT',FN) then
  278.         begin
  279.           Log[FN]^.Found:=True;
  280.           if Log[FN]^.Checksum=cs then writeln('Boot Sector verified.')
  281.           else
  282.             begin
  283.               write('Boot Sector has changed! Update log file? ');
  284.               write(LstFile,'Boot Sector has changed! Update log file? ');
  285.               repeat cmd:=UpCase(ReadKey) until cmd in ['Y','N'];
  286.               if cmd='Y' then Log[FN]^.Checksum:=cs;
  287.               writeln(cmd);
  288.               writeln(LstFile,cmd);
  289.             end;
  290.         end
  291.       else
  292.         begin
  293.           writeln('Boot Sector data ADDED to log.');
  294.           writeln(LstFile,'Boot Sector data ADDED to log.');
  295.           LogEntries:=LogEntries+1;
  296.           new(Log[LogEntries]);
  297.           Log[LogEntries]^.Name:='**BOOT';
  298.           Log[LogEntries]^.Checksum:=cs;
  299.           Log[LogEntries]^.Found:=True;
  300.         end;
  301.     end;
  302. end;
  303.  
  304. {This procedure removes files from the log that have been deleted on the
  305.  system. Of course, it allows the user to decide whether to remove them or
  306.  not.}
  307. procedure PurgeFile(j:word);
  308. var
  309.   cmd              :char;
  310.   i                :word;
  311. begin
  312.   write(Log[j]^.Name,' was not found. Delete from log file? ',#7,#7,#7);
  313.   write(LstFile,Log[j]^.Name,' was not found. Delete from log file? ');
  314.   repeat cmd:=UpCase(ReadKey) until cmd in ['Y','N'];
  315.   if cmd='Y' then
  316.     begin
  317.       for i:=j to LogEntries-1 do
  318.         Log[i]^:=Log[i+1]^;
  319.       LogEntries:=LogEntries-1;
  320.     end;
  321.   writeln(cmd);
  322.   writeln(LstFile,cmd);
  323. end;
  324.  
  325. begin
  326.   writeln('GB-INTEG Ver 1.00, (C) 1995 American Eagle Publications, Inc.');
  327.  
  328.   assign(LogFile,'\GBINTEG.DAT');             {Load the log file into memory}
  329. {$I-}
  330.   reset(LogFile);
  331. {$I+}
  332.   if IOResult<>0 then
  333.     LogEntries:=0
  334.   else
  335.     begin
  336.       for LogEntries:=1 to FileSize(LogFile) do
  337.         begin
  338.           new(Log[LogEntries]);
  339.           read(LogFile,Log[LogEntries]^);
  340.         end;
  341.       close(LogFile);
  342.     end;
  343.  
  344.   assign(LstFile,'GBINTEG.LST');                    {Create the listing file}
  345.   rewrite(LstFile);
  346.  
  347.   {Take care of directory maintenance}
  348.   if ParamCount=1 then SearchDir:=ParamStr(1) else SearchDir:='\';
  349.   GetDir(0,CurrDir);
  350.  
  351.  
  352.   ChDir(SearchDir);
  353.   if SearchDir[length(SearchDir)]<>'\' then SearchDir:=SearchDir+'\';
  354.   check_boot;                                        {check the boot sectors}
  355.   check_dir(SearchDir);                                     {check integrity}
  356.  
  357.   j:=1;
  358.   while j<=LogEntries do                               {handle missing files}
  359.     begin
  360.       if Log[j]^.Found then j:=j+1
  361.       else PurgeFile(j);
  362.     end;
  363.  
  364.   ChDir(CurrDir);
  365.   rewrite(LogFile);                                         {update log file}
  366.   for j:=1 to LogEntries do
  367.     begin
  368.       Log[j]^.Found:=False;        {reset these flags before writing to disk}
  369.       write(LogFile,Log[j]^);
  370.     end;
  371.   close(LogFile);
  372.  
  373.   writeln(LogEntries,' files in current log file.');
  374.   writeln(LstFile,LogEntries,' files in current log file.');
  375.   close(LstFile);
  376. end.
  377.